package com.maozzi.service.user.business;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maozzi.api.user.UserService;
import com.maozzi.api.user.enums.UserTypeEnum;
import com.maozzi.api.user.model.TokenDTO;
import com.maozzi.api.user.model.UserDTO;
import com.maozzi.common.enums.BizCodeEnum;
import com.maozzi.common.exception.BizException;
import com.maozzi.common.model.PageDTO;
import com.maozzi.common.model.PageParam;
import com.maozzi.common.util.CloneUtil;
import com.maozzi.common.util.ParamCheckUtil;
import com.maozzi.common.util.TokenUtil;
import com.maozzi.service.user.domain.UserDomainService;
import com.maozzi.service.user.repository.model.User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 用户 service
 *
 * @author maozi
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserDomainService userDomainService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signup(UserDTO dto) throws BizException {
        ParamCheckUtil.notNull(dto, "参数错误");
        dto.setType(UserTypeEnum.NORMAL.getCode());

        User user = CloneUtil.to(dto, User.class);
        userDomainService.signup(user);
    }

    @Override
    public UserDTO getUser(Long userId) throws BizException {
        ParamCheckUtil.notNull(userId, "用户id为空");

        User user = userDomainService.getUser(userId);
        return CloneUtil.to(user, UserDTO.class);
    }

    @Override
    public TokenDTO signIn(String name, String password) throws BizException {
        User user = userDomainService.getUser(name, password);
        if (ObjectUtils.isEmpty(user)) {
            throw new BizException(BizCodeEnum.FAILED_OPERATION, "用户名或密码错误");
        }

        UserDTO userDTO = CloneUtil.to(user, UserDTO.class);
        TokenDTO tokenDTO = CloneUtil.to(userDTO, TokenDTO.class);

        Objects.requireNonNull(tokenDTO).setToken(TokenUtil.getToken(tokenDTO.getId()));
        return tokenDTO;
    }

    @Override
    public PageDTO<UserDTO> page(UserDTO dto, PageParam pageParam) throws BizException {
        if (Objects.isNull(pageParam)) {
            pageParam = new PageParam(1, 10);
        }

        Page<User> page = Page.of(pageParam.getPage(), pageParam.getPageSize());
        LambdaQueryWrapper<User> query = Wrappers.lambdaQuery(User.class)
                .eq(User::getDeleted, false)
                .orderByDesc(User::getId);
        if (Objects.nonNull(dto)) {
            // 查询名称
            String name = dto.getName();
            if (StringUtils.hasText(name)) {
                query.likeLeft(User::getName, name);
            }

            // 查询类型
            Byte type = dto.getType();
            if (Objects.nonNull(type)) {
                query.eq(User::getType, type);
            }

            // 查询注册时间
            Date start = dto.getStart();
            Date end = dto.getEnd();
            if (Objects.nonNull(start) && Objects.nonNull(end)) {
                query.between(User::getCreateDate, start, end);
            }
        }

        page = userDomainService.page(page, query);

        return CloneUtil.toPageDTO(page, UserDTO.class);
    }

    @Override
    public PageDTO<UserDTO> adminPage(UserDTO dto, PageParam pageParam) throws BizException {
        if (Objects.isNull(pageParam)) {
            pageParam = new PageParam(1, 10);
        }

        Page<User> page = Page.of(pageParam.getPage(), pageParam.getPageSize());
        LambdaQueryWrapper<User> query = Wrappers.lambdaQuery(User.class)
                .in(User::getType, UserTypeEnum.ADMIN.getCode(), UserTypeEnum.SUPER_ADMIN.getCode())
                .eq(User::getDeleted, false)
                .orderByDesc(User::getId);
        if (Objects.nonNull(dto)) {
            // 查询名称
            String name = dto.getName();
            if (StringUtils.hasText(name)) {
                query.likeLeft(User::getName, name);
            }

            // 查询注册时间
            Date start = dto.getStart();
            Date end = dto.getEnd();
            if (Objects.nonNull(start) && Objects.nonNull(end)) {
                query.between(User::getCreateDate, start, end);
            }
        }

        page = userDomainService.page(page, query);

        return CloneUtil.toPageDTO(page, UserDTO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addAdmin(List<Long> userIds) throws BizException {
        ParamCheckUtil.notNull(userIds, "添加管理员参数错误");

        userIds = userIds.stream().distinct().collect(Collectors.toList());
        // 查询 userIds 是否存在无效id
        List<User> userList = userDomainService.userListBatch(userIds);
        if (userIds.size() != userList.size()) {
            throw new BizException(BizCodeEnum.WRONG_PARAMETERS, "存在无效用户ID");
        }

        // 批量更新
        return userDomainService.updateUserTypeById(userIds, UserTypeEnum.ADMIN);
    }
}
